package covertjava.util;

import java.util.Properties;
import java.io.*;
import java.net.URL;

import org.apache.log4j.*;

/**
 * AppProperties extends java.util.Properties and adds convenience methods
 * for reading properties from a file and getting typed properties
 * such as boolean and int
 * <p>Copyright 2004 by Sams Publishing
 * @author Alex Kalinovsky
 */

public class AppProperties extends Properties {

    static Logger logger = Logger.getLogger(AppProperties.class.getName());


    public AppProperties(Properties defaults) throws Exception {
        super(defaults);
    }

    /**
     * Instantiates the object and reads it from a given file
     */

    public AppProperties(String fileName) throws Exception {
        this(fileName, null);
    }

    /**
     * Constructor to load the property file and also specifies the default properties
     * <b> <font color="red"> Warning: Default properties is not returned by Properties
     * class methods like entrySet, keySet(), keys(). Use propertyNames() to retrieve
     * the default property keys. </font> </b>
     *
     * @param fileName full path name to the property file
     * @param defaults Default Properties object.
     * @throws Exception
     */
    public AppProperties(String fileName, Properties defaults) throws Exception {
        super(defaults);

        logger.info("Constructor, fileName = " + fileName);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(fileName);
            load(fis);
        } finally {
            if (fis != null)
                fis.close();
        }
    }


    public AppProperties(URL url) throws Exception {
        this(url, null);
    }

    public AppProperties(URL url, Properties defaults) throws Exception {
        super(defaults);

        logger.info("Constructor, url = " + url);
        BufferedInputStream bufIStream = null;
        try {
            bufIStream = new BufferedInputStream(url.openStream());
            load(bufIStream);
        } finally {
            if (bufIStream != null)
                bufIStream.close();
        }
    }


    /**
     * Loads the file into the existing properties.
     * @param fileName full path to the location of the file
     * @throws IOException
     */
    public void load(String fileName)
            throws IOException {
        logger.debug("load method, fileName = " + fileName);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(fileName);
            load(fis);
        } finally {
            if (fis != null)
                fis.close();
        }
    }

    public boolean getBooleanProperty(String key, boolean defValue) {
        String value = getProperty(key);
        if (value == null)
            return defValue;
        else
            return value.equalsIgnoreCase("true");
    }

    public void setBooleanProperty(String key, boolean value) {
        setProperty(key, value ? "true" : "false");
    }

    public int getIntProperty(String key, int defValue) {
        String value = getProperty(key);
        int intValue = defValue;
        if (value == null)
            return intValue;
        else
            try {
                intValue = Integer.parseInt(value);
            } catch (NumberFormatException ne) {
                logger.error("Invalid integer value \"" + value + "\" for key " + key, ne);
            }
        return intValue;
    }

    public void setIntProperty(String key, int value) {
        setProperty(key, String.valueOf(value));
    }

    public long getLongProperty(String key, long defValue) {
        String value = getProperty(key);
        if (value == null)
            return defValue;
        else
            return Long.parseLong(value);
    }

    public void setLongProperty(String key, long value) {
        setProperty(key, String.valueOf(value));
    }

}
